﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Pay.DTO;
using Pay.IService;
using Pay.Core;
using Pay.TO;
using System.Linq;
using Flurl.Http;
using Newtonsoft.Json.Linq;

namespace Pay.Service {
	public class SxyPayService : ServiceBase2, IPayService, IDisposable {
		private ISettingService _iSettingService;
		private IMerchantService _iMerchantService;
		private IChargeService _iChargeService;
		private IPayHtmlService _iPayHtmlService;
		private IOrderService _iOrderService;
		private IPayNotifyService _iPayNotifyService;
		private SxyPaySign _sxyPaySign;
		public SxyPayService(IUnitOfWork iUnitOfWork, ISettingService iSettingService,
							IMerchantService iMerchantService, IChargeService iChargeService,
							 IPayHtmlService iPayHtmlService, IOrderService iOrderService,
							 IPayNotifyService iPayNotifyService) : base(iUnitOfWork) {
			_iSettingService = iSettingService;
			_iMerchantService = iMerchantService;
			_iChargeService = iChargeService;
			_iPayHtmlService = iPayHtmlService;
			_iOrderService = iOrderService;
			_iPayNotifyService = iPayNotifyService;
			_sxyPaySign = new SxyPaySign();
		}

		public Task<transfer_result> AgencyFund(apply_receive model) {
			throw new NotImplementedException();
		}

		public Task<certify_verify_result> CertifyVerify(certify_verify model) {
			throw new NotImplementedException();
		}

		public int DealItp(long id) {
			throw new NotImplementedException();
		}

		public Task<gateway_pay_result> GatewayPay(gateway_pay_model model) {
			throw new NotImplementedException();
		}

		public List<type_setting> GatewayPayBank() {
			throw new NotImplementedException();
		}

		public async Task<pay_notity> GatewayPayQuery(refund_model_query model) {
			var pay_html = _iPayHtmlService.Get(model.merchant_no, model.order_no);
			if (pay_html != null) {
				var query = new sxy_gateway_query { 
					v_mid = _sxyPaySign.Partner,
					v_oid = model.transaction_no
				};
				var resultApi = await _sxyPaySign.PayGateway<sxy_gateway_query_result>(query,"/merchant/order/order_ack_oid_list.jsp");
				if (resultApi != null) {
					if (resultApi.v_status == "0" && resultApi.v_pstatus == "1") {
						int result = _iOrderService.PaySuceess(pay_html, resultApi.v_oid, DateTime.Now);
						var charge = pay_html.charge.ToObject<charge_dto>();
						var notifyResult = await Notify(charge.merchant_no, charge.order_no);
						if (notifyResult != "OK") {
							//创建通知消息对象
							_iPayNotifyService.Save(new pay_notify_dto {
								merchant_no = charge.merchant_no,
								order_no = charge.order_no,
								pay_channel = charge.pay_info.pay_channel,
								type = 1,
								status = 2,
								create_time = DateTime.Now
							});
						}
						_iPayHtmlService.Remove(pay_html.id);
						return ApiResultToJson.Json("支付成功", new pay_notity {
							order_no = model.order_no,
							tran_amount = resultApi.v_amount,
							transaction_no = model.transaction_no,
							pay_time = DateTime.Now
						});
					}
				}
			}
			return ApiResultToJson.Json<pay_notity>("网关支付查询异常");
		}

		public Task<refund_result> GatewayPayRefund(refund_model model) {
			throw new NotImplementedException();
		}

		public Task<refund_result> GatewayRefundQuery(refund_model_query model) {
			throw new NotImplementedException();
		}

		public Task<ApiResultMessage> InsteadReceive(verify_model_sms model) {
			throw new NotImplementedException();
		}

		public Task<ApiResultMessage> InsteadReceive(verify_model model) {
			throw new NotImplementedException();
		}

		public Task<int> ItpToFile(DateTime create_date) {
			throw new NotImplementedException();
		}

		public async Task<mall_result> MallPay(mall_model model) {
			var log = IocHelper.Get<ILogHelper>("info");
            var notifyUrl = string.Format("{0}/pay/sxy_back_notify", _iSettingService.Get().site.api_url);
			var shipping = new shipping_dto();
			if (model.shipping != null) {
				shipping.ship_to = model.shipping.ship_to;
				shipping.region_id = model.shipping.area_id.HasValue ? model.shipping.area_id.Value : model.shipping.city_id;
				shipping.phone = model.shipping.phone; shipping.address = model.shipping.address;
				shipping.region_name = model.shipping.region_name;
				shipping.id_card = model.shipping.id_card;
				shipping.real_name = model.shipping.real_name;
				shipping.card_negative = model.shipping.card_negative;
				shipping.card_positive = model.shipping.card_positive;
			} else {
				throw new ServerErrorException("收货地址不能为空！");
			}
            //匿名购买随机生成一个
            if (string.IsNullOrEmpty(model.bind_no))
                model.bind_no = DtoHelper.GenerateOrderNumber();
			int count = 0;
			model.orders.ForEach(c => { c.shipping_type = model.shipping_type; c.shipping = shipping; count += c.order_items.Sum(t => t.quantity); });
			//下单时间
			string orderDateTime = DateTime.Now.ToString("yyyyMMddHHmmss");
			string ymd = DateTime.Now.ToString("yyyyMMdd");
			string hms = DateTime.Now.ToString("hhmmss");
			string v_oid = ymd + "-" + _sxyPaySign.Partner + "-" + hms;
			//var charge = _iChargeService.AddBySeaPay(model);
            //todo:需构造收款信息
			var htmls = new List<pay_html_dto>();
			var order_html = new pay_html_dto {
				id = v_oid,
				html = model.orders.ToJson(),
				merchant_no = model.merchant_no,
				order_no = model.order_no,
				charge = model.order_no,
				create_time = orderDateTime.ToDateTime(),
                pay_type = model.req_method.ToString()
			};
			htmls.Add(order_html);

			var sxy_pay = new sxy_gateway_pay {
				v_mid = _sxyPaySign.Partner,
				v_oid = v_oid,
				v_rcvname = _sxyPaySign.Partner,
				v_rcvaddr = _sxyPaySign.Partner,
				v_rcvtel = model.shipping.phone,
				v_rcvpost = _sxyPaySign.Partner,
				v_amount = (Convert.ToDecimal(model.tran_amount) / 100).ToString(),
				v_ymd = ymd,
				v_ordername = _sxyPaySign.Partner,
				v_url = notifyUrl,
				v_merdata = model.orders.Sum(c => c.amount).ToString(),
				v_idnumber = System.Web.HttpUtility.UrlEncode(model.shipping.id_card, System.Text.Encoding.UTF8).ToUpper(),
				v_idname = System.Web.HttpUtility.UrlEncode(model.shipping.real_name, System.Text.Encoding.UTF8).ToUpper(),
				v_idaddress = System.Web.HttpUtility.UrlEncode("none", System.Text.Encoding.UTF8).ToUpper(),
				v_userref = System.Web.HttpUtility.UrlEncode(model.bind_no, System.Text.Encoding.UTF8).ToUpper(),
				v_producttype = System.Web.HttpUtility.UrlEncode("1004", System.Text.Encoding.UTF8).ToUpper(),
				v_merdata6 = System.Web.HttpUtility.UrlEncode("10040002", System.Text.Encoding.UTF8).ToUpper(),
				v_itemquantity = count.ToString()
			};
			sxy_pay.v_md5info = _sxyPaySign.Sign(sxy_pay);
			log.Info(sxy_pay.ToJson());
			var req_id = Guid.NewGuid().ToString("N");
			var request_url = string.Format("{0}/pay/sxy_front/{1}", _iSettingService.Get().site.api_url, req_id);
			var pay_html = new pay_html_dto {
				id = req_id,
				html = sxy_pay.ToJson(),
				merchant_no = model.merchant_no,
				order_no = model.merchant_no,
				charge = _sxyPaySign.sxy_api_url,
				create_time = orderDateTime.ToDateTime()
			};
			htmls.Add(pay_html);
			var ok = _iPayHtmlService.Save(htmls);
			if (ok) {
				//用于h5注册
				if (model.req_method == 2) {
					var result = _iOrderService.WaitPayOrder(order_html);
#if DEBUG
                    result = _iOrderService.PayH5Success(order_html, v_oid, DateTime.Now);
					_iPayHtmlService.Remove(pay_html.id);
#endif
                }
				var data = new mall_result { order_no = model.order_no, code_url = request_url };
				return ApiResultToJson.Json(data);
			}
			return await ApiResultToJson.JsonAsync<mall_result>("sql-data:html数据保存失败");
		}

		public Task<merchant_register_result> MerchantModify(long bind_id, string settle_type, PayChannel channel = PayChannel.None) {
			throw new NotImplementedException();
		}

		public Task<merchant_register_result> MerchantRegister(merchant_register_model dto, string opt) {
			throw new NotImplementedException();
		}

		public Task<merchant_register_result> MerchantRegister(long bind_id, string settle_type, PayChannel channel = PayChannel.None) {
			throw new NotImplementedException();
		}

		public Task<native_result> NativePay(native_model obj) {
			throw new NotImplementedException();
		}

		public async Task<string> Notify(string merchant_no, string order_no) {
			string result = string.Empty;
			charge_dto order = _iChargeService.Get(merchant_no, order_no);
			try {
				var data = new pay_notity {
					tran_amount = ((int)(order.order_amount * 100)).ToString(),
					order_no = order.order_no,
					transaction_no = order.pay_info.transaction_no,
					pay_time = order.pay_info.pay_time.HasValue ? order.pay_info.pay_time.Value : order.order_time,
					status = (order.status == ChargeStatus.Finish ? 1 : 2)
				};
				data.result_msg = (data.status == 1 ? "支付成功" : order.fail);
				if (string.IsNullOrEmpty(order.notify)) return "OK";
				var notify_result = await order.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveJson<ResultMessage<string>>();
				result = notify_result.data;
				var log = IocHelper.Get<ILogHelper>("info");
				log.Info(order.order_no + ":" + notify_result.ToJson());
			} catch (Exception ex) {
				var log = IocHelper.Get<ILogHelper>("info");
				log.Error("订单通道查询异常:" + order.order_no);
				string message = string.Format("消息类型：{0}\r\n消息内容：{1}\r\n引发异常的方法：{2}\r\n引发异常源：{3}"
								, ex.GetType().Name, ex.Message, ex.TargetSite, ex.Source + ex.StackTrace);
				log.Error(message);
			}
			return result;
		}

		public Task<string> NotifyTransfer(string merchant_no, string order_no) {
			throw new NotImplementedException();
		}

		public Task<quick_pay_result> QuickPay(quick_sms_model model) {
			throw new NotImplementedException();
		}

		public Task<quick_pay_result> QuickPay(quick_pay_model model) {
			throw new NotImplementedException();
		}

		public Task<pay_notity> QuickPayQuery(refund_model_query model) {
			throw new NotImplementedException();
		}

		public Task<refund_result> QuickPayRefund(refund_model model) {
			throw new NotImplementedException();
		}

		public Task<refund_result> QuickPayRefundQuery(refund_model_query model) {
			throw new NotImplementedException();
		}

		public Task<ApiResultMessage> QuickPaySendsms(quick_sendsms_model model) {
			throw new NotImplementedException();
		}

		public Task<quota_result> Quota(string merchant_no, string busiType) {
			throw new NotImplementedException();
		}

		public Task<transfer_result> ReTransfer(long id) {
			throw new NotImplementedException();
		}

        public Task<transfer_result> TokenTransfer(long id) {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TokenTransferQuery(transfer_query model) {
            throw new NotImplementedException();
        }

        public Task<batch_transfer_result> Transfer(batch_transfer model) {
			throw new NotImplementedException();
		}

		public Task<transfer_result> Transfer(apply_transfer model) {
			throw new NotImplementedException();
		}

		public Task<int> TransferBack(long batchId, string noticeTranId, long merchant_id) {
			throw new NotImplementedException();
		}

		public Task<int> TransferNotify(long batchId, string batchFileName, long merchant_id) {
			throw new NotImplementedException();
		}

		public Task<transfer_result> TransferQuery(transfer_query model) {
			throw new NotImplementedException();
		}
	}
}
